package com.gisquest.cloud.common.exception;

import com.alibaba.fastjson.JSON;
import com.gisquest.cloud.common.enums.BizEnum;
import com.gisquest.cloud.entity.vo.RestResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;

/**
 * @Author guowei
 * @Date 2020/6/17 10:55
 * @Description:异常返回
 **/
@ControllerAdvice
public class ExceptionAdvice {

  private Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

  @ExceptionHandler({Exception.class})
  public ResponseEntity<RestResult<String>> handleException(Exception e) {
    this.logger.error(e.getMessage(), e);

    while ((e instanceof UndeclaredThrowableException)) {
      UndeclaredThrowableException ite = (UndeclaredThrowableException) e;
      e = (Exception) ite.getUndeclaredThrowable();
    }
    while ((e instanceof InvocationTargetException)) {
      InvocationTargetException ite = (InvocationTargetException) e;
      e = (Exception) ite.getTargetException();
    }

    RestResult exMsg = new RestResult();
    if (isServiceException(e))
      exMsg = exMsg.makeFailResult(e.getMessage(),JSON.toJSONString(e.getStackTrace()));
    else {
      exMsg = new RestResult().makeFailResult(BizEnum.SYSTEM_UNKNOW_ERROR.getMessage(),BizEnum.SYSTEM_UNKNOW_ERROR.getMessage());
    }

    HttpHeaders headers = new HttpHeaders();
    headers.set("Content-type", "application/json;charset=UTF-8");
    headers.add("icop-content-type", "exception");
    return new ResponseEntity(exMsg, headers, HttpStatus.OK);
  }


  private boolean isServiceException(Throwable exb) {
    boolean rs = false;
    Throwable ex = exb;
    if ((ex instanceof BizException)) {
      rs = true;
    }
    while ((!rs) && (ex.getCause() != null)) {
      ex = ex.getCause();
      if ((ex instanceof BizException)) {
        rs = true;
      }
    }
    return rs;
  }


}
